// Copyright (c) 2020 Presto Labs Pte. Ltd.
// Author: donggu

#include "coin2/exchange/base/feed_util/book_builder.h"

#include <gtest/gtest.h>

TEST(BookBuilder, PriceQty) {
  auto pq = PriceQty(3.2, 4.5);
  EXPECT_EQ(pq.price, 3.2);
  EXPECT_EQ(pq.qty, 4.5);
}

TEST(BookBuilder, OnSnapshot) {
  auto book = BookBuilder(BookBuilder::SNAPSHOT);
  std::vector<PriceQty> asks = {{100, 10}, {200, 30}, {300, 40}};
  std::vector<PriceQty> bids = {{4, 50}, {2, 20}, {5, 1232}};
  std::vector<PriceQty> bids_sorted = {{5, 1232}, {4, 50}, {2, 20}};

  auto t = book.NewTransaction(567);
  for (const auto& pq : asks) {
    t.UpdateAsk(pq.price, pq.qty);
  }
  for (const auto& pq : bids) {
    t.UpdateBid(pq.price, pq.qty);
  }

  EXPECT_EQ(book.Timestamp(), 567);
  EXPECT_EQ(book.Ask0()->price, 100);
  EXPECT_EQ(book.Ask0()->qty, 10);
  EXPECT_EQ(book.Bid0()->price, 5);
  EXPECT_EQ(book.Bid0()->qty, 1232);

  EXPECT_EQ(book.AskN(1)->price, 200);
  EXPECT_EQ(book.AskN(2)->qty, 40);
  EXPECT_EQ(book.BidN(1)->price, 4);
  EXPECT_EQ(book.BidN(2)->qty, 20);

  EXPECT_FALSE(book.AskN(3).has_value());
  EXPECT_FALSE(book.BidN(4).has_value());

  auto asks01 = book.Asks(2);
  EXPECT_EQ(asks01.size(), 2);
  EXPECT_EQ(asks01[0].price, 100);
  EXPECT_EQ(asks01[1].qty, 30);

  std::vector<PriceQty> out;
  for (auto it = book.AskBegin(); it != book.AskEnd(); it++) {
    out.emplace_back(it->first, it->second);
  }
  EXPECT_TRUE(asks == out);

  out.clear();
  for (auto it = book.BidBegin(); it != book.BidEnd(); it++) {
    out.emplace_back(it->first, it->second);
  }
  EXPECT_TRUE(bids_sorted == out);
}
